package com.lock.redisLocks.jedix;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

import com.lock.redisLocks.RedisHelper;
import com.lock.redisLocks.annotation.Recommend;
import io.lettuce.core.KeyValue;
import io.lettuce.core.Range;
import io.lettuce.core.ScoredValue;
import io.lettuce.core.SetArgs;
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;
import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands;
import redis.clients.jedis.BinaryClient.LIST_POSITION;
// import redis.clients.jedis.BitPosParams;
// import redis.clients.jedis.GeoCoordinate;
// import redis.clients.jedis.GeoRadiusResponse;
// import redis.clients.jedis.GeoUnit;
// import redis.clients.jedis.ScanParams;
// import redis.clients.jedis.ScanResult;
// import redis.clients.jedis.SortingParams;
import redis.clients.jedis.Tuple;

public class JedixLettuceClusterProxy implements Jedix {

	private final boolean usePool;

	private final RedisHelper.RedisConfigType redisConfigType;
	private final RedisHelper.ProviderConfigType providerConfigType;

	private final StatefulRedisClusterConnection<String, String> conn;
	private final RedisAdvancedClusterCommands<String, String> syncClusterCmd;

	public JedixLettuceClusterProxy(StatefulRedisClusterConnection<String, String> conn, boolean usePool,
									RedisHelper.RedisConfigType redisConfigType, RedisHelper.ProviderConfigType providerConfigType) {

		this.conn = conn;
		this.syncClusterCmd = conn.sync();
		this.usePool = usePool;
		this.redisConfigType = redisConfigType;
		this.providerConfigType = providerConfigType;
	}

	@SuppressWarnings("unchecked")
	@Override
	public StatefulRedisClusterConnection<String, String> getOriginImpl() {
		return conn;
	}

	public boolean isUsePool() {
		return usePool;
	}

	@Override
	public RedisHelper.RedisConfigType getRedisConfigType() {
		return redisConfigType;
	}

	@Override
	public RedisHelper.ProviderConfigType getProviderConfigType() {
		return providerConfigType;
	}

	@Override
	public void close() {
		if (usePool) {
			conn.close();
		}

	}

	private RedisAdvancedClusterCommands<String, String> getJedisCmdsImpl() {
		return syncClusterCmd;
	}

	private RedisAdvancedClusterCommands<String, String> getBasicCmdsImpl() {
		return syncClusterCmd;
	}

	private RedisAdvancedClusterCommands<String, String> getMultiKeyCmdsImpl() {
		return syncClusterCmd;
	}

	@Override
	public String ping() {
		return getBasicCmdsImpl().ping();
	}

	@Override
	public String quit() {

		return getBasicCmdsImpl().quit();
	}

	@Override
	public String flushDB() {
		return getBasicCmdsImpl().flushdb();
	}

	@Override
	public Long dbSize() {
		return getBasicCmdsImpl().dbsize();
	}

	@Override
	public String flushAll() {
		return getBasicCmdsImpl().flushall();
	}

	@Override
	public String auth(String password) {
		return getBasicCmdsImpl().auth(password);
	}

	@Override
	public String save() {
		return getBasicCmdsImpl().save();
	}

	@Override
	public String bgsave() {
		return getBasicCmdsImpl().bgsave();
	}

	@Override
	public String bgrewriteaof() {
		return getBasicCmdsImpl().bgrewriteaof();
	}

	@Override
	public Long lastsave() {
		return getBasicCmdsImpl().dbsize();
	}

	@Override
	public String info() {
		return getBasicCmdsImpl().info();
	}

	@Override
	public String info(String section) {
		return getBasicCmdsImpl().info(section);
	}

	@Override
	public String slaveof(String host, int port) {
		return getBasicCmdsImpl().slaveof(host, port);
	}

	@Override
	public String slaveofNoOne() {
		return getBasicCmdsImpl().slaveofNoOne();
	}

	@Override
	public String configResetStat() {
		return getBasicCmdsImpl().configResetstat();
	}

	@Override
	public Long waitReplicas(int replicas, long timeout) {
		return getBasicCmdsImpl().waitForReplication(replicas, timeout);
	}

	//////////////////////////////////////////////////////////////////
	@Override
	public String set(String key, String value) {
		return getJedisCmdsImpl().set(key, value);
	}

	String NX = "NX";
	String XX = "XX";
	String EX = "EX";
	String PX = "PX";

	@Override
	public String set(String key, String value, String nxxx, String expx, long time) {
		SetArgs setArgs = null;
		if (NX.equals(nxxx)) {
			if (EX.equals(expx)) {
				setArgs = SetArgs.Builder.nx().ex(time);
			} else if (PX.equals(expx)) {
				setArgs = SetArgs.Builder.nx().px(time);
			} else {
				throw new IllegalArgumentException("Illegal expx:" + expx);
			}
		} else if (XX.equals(nxxx)) {
			if (EX.equals(expx)) {
				setArgs = SetArgs.Builder.xx().ex(time);
			} else if (PX.equals(expx)) {
				setArgs = SetArgs.Builder.xx().px(time);
			} else {
				throw new IllegalArgumentException("Illegal expx:" + expx);
			}
		} else {
			throw new IllegalArgumentException("Illegal nxxx:" + nxxx);
		}

		return getJedisCmdsImpl().set(key, value, setArgs);

	}

	@Override
	public String set(String key, String value, String nxxx) {
		SetArgs setArgs = null;
		if (NX.equals(nxxx)) {
			setArgs = SetArgs.Builder.nx();
		} else if (XX.equals(nxxx)) {
			setArgs = SetArgs.Builder.xx();
		} else {
			throw new IllegalArgumentException("Illegal nxxx:" + nxxx);
		}
		return getJedisCmdsImpl().set(key, value, setArgs);

	}

	@Override
	public String get(String key) {
		return getJedisCmdsImpl().get(key);

	}

	@Override
	public Boolean exists(String key) {
		return getJedisCmdsImpl().exists(key) == 1L;

	}

	@Override
	public Long persist(String key) {
		return getJedisCmdsImpl().persist(key) ? 1L : 0L;

	}

	@Override
	public String type(String key) {
		return getJedisCmdsImpl().type(key);

	}

	@Override
	public Long expire(String key, int seconds) {
		return getJedisCmdsImpl().expire(key, seconds) ? 1L : 0L;

	}

	@Override
	public Long pexpire(String key, long milliseconds) {
		return getJedisCmdsImpl().pexpire(key, milliseconds) ? 1L : 0L;

	}

	@Override
	public Long expireAt(String key, long unixTime) {
		return getJedisCmdsImpl().expireat(key, unixTime) ? 1L : 0L;

	}

	@Override
	public Long pexpireAt(String key, long millisecondsTimestamp) {
		return getJedisCmdsImpl().expireat(key, millisecondsTimestamp) ? 1L : 0L;
	}

	@Override
	public Long ttl(String key) {
		return getJedisCmdsImpl().ttl(key);

	}

	@Override
	public Long pttl(String key) {
		return getJedisCmdsImpl().pttl(key);

	}

	@Override
	public Boolean setbit(String key, long offset, boolean value) {
		int bit = value ? 1 : 0;
		return getJedisCmdsImpl().setbit(key, offset, bit) == 1L;

	}

	@Override
	public Boolean getbit(String key, long offset) {
		return getJedisCmdsImpl().getbit(key, offset) == 1;

	}

	@Override
	public Long setrange(String key, long offset, String value) {
		return getJedisCmdsImpl().setrange(key, offset, value);

	}

	@Override
	public String getrange(String key, long startOffset, long endOffset) {
		return getJedisCmdsImpl().getrange(key, startOffset, endOffset);

	}

	@Override
	public String getSet(String key, String value) {
		return getJedisCmdsImpl().getset(key, value);

	}

	@Override
	public Long setnx(String key, String value) {
		return getJedisCmdsImpl().setnx(key, value) ? 1L : 0L;

	}

	@Override
	public String setex(String key, int seconds, String value) {
		return getJedisCmdsImpl().setex(key, seconds, value);

	}

	@Override
	public String psetex(String key, long milliseconds, String value) {
		return getJedisCmdsImpl().psetex(key, milliseconds, value);

	}

	@Override
	public Long decrBy(String key, long integer) {
		return getJedisCmdsImpl().decrby(key, integer);

	}

	@Override
	public Long decr(String key) {
		return getJedisCmdsImpl().decr(key);

	}

	@Override
	public Long incrBy(String key, long integer) {
		return getJedisCmdsImpl().incrby(key, integer);

	}

	@Override
	public Double incrByFloat(String key, double value) {
		return getJedisCmdsImpl().incrbyfloat(key, value);

	}

	@Override
	public Long incr(String key) {
		return getJedisCmdsImpl().incr(key);

	}

	@Override
	public Long append(String key, String value) {
		return getJedisCmdsImpl().append(key, value);

	}

	@Override
	public Long hset(String key, String field, String value) {

		return getJedisCmdsImpl().hset(key, field, value) ? 1L : 0L;

	}

	@Override
	public String hget(String key, String field) {
		return getJedisCmdsImpl().hget(key, field);

	}

	@Override
	public Long hsetnx(String key, String field, String value) {
		return getJedisCmdsImpl().hsetnx(key, field, value) ? 1L : 0L;

	}

	@Override
	public String hmset(String key, Map<String, String> hash) {
		return getJedisCmdsImpl().hmset(key, hash);

	}

	/**
	 * 返回类型有了装换, 建议用hmgetLettuce
	 */
	@Override
	@Deprecated
	public List<String> hmget(String key, String... fields) {
		List<String> listStr = new ArrayList<>();
		List<KeyValue<String, String>> list = getJedisCmdsImpl().hmget(key, fields);
		for (String field : fields) {
			for (KeyValue<String, String> kv : list) {
				if (kv.getKey().equals(field)) {
					listStr.add(kv.hasValue() ? kv.getValue() : null);
				}
			}
		}
		return listStr;
	}

	/**
	 * Lettuce实现返回数据类型不同
	 * 
	 * @param key
	 * @param fields
	 * @return
	 */
	@Recommend(from = "hmget")
	public List<KeyValue<String, String>> hmget4Lettuce(String key, String... fields) {
		return getJedisCmdsImpl().hmget(key, fields);
	}

	@Override
	public Long hincrBy(String key, String field, long value) {
		return getJedisCmdsImpl().hincrby(key, field, value);

	}

	@Override
	public Double hincrByFloat(String key, String field, double value) {
		return getJedisCmdsImpl().hincrbyfloat(key, field, value);

	}

	@Override
	public Boolean hexists(String key, String field) {
		return getJedisCmdsImpl().hexists(key, field);

	}

	@Override
	public Long hdel(String key, String... field) {
		return getJedisCmdsImpl().hdel(key, field);

	}

	@Override
	public Long hlen(String key) {
		return getJedisCmdsImpl().hlen(key);

	}

	@Override
	public Set<String> hkeys(String key) {
		List<String> list = getJedisCmdsImpl().hkeys(key);
		return Sets.newHashSet(list);
	}

	@Override
	public List<String> hvals(String key) {
		return getJedisCmdsImpl().hvals(key);

	}

	@Override
	public Map<String, String> hgetAll(String key) {
		return getJedisCmdsImpl().hgetall(key);

	}

	@Override
	public Long rpush(String key, String... string) {
		return getJedisCmdsImpl().rpush(key, string);

	}

	@Override
	public Long lpush(String key, String... string) {
		return getJedisCmdsImpl().lpush(key, string);

	}

	@Override
	public Long llen(String key) {
		return getJedisCmdsImpl().llen(key);

	}

	@Override
	public List<String> lrange(String key, long start, long end) {
		return getJedisCmdsImpl().lrange(key, start, end);

	}

	@Override
	public String ltrim(String key, long start, long end) {
		return getJedisCmdsImpl().ltrim(key, start, end);

	}

	@Override
	public String lindex(String key, long index) {
		return getJedisCmdsImpl().lindex(key, index);

	}

	@Override
	public String lset(String key, long index, String value) {
		return getJedisCmdsImpl().lset(key, index, value);

	}

	@Override
	public Long lrem(String key, long count, String value) {
		return getJedisCmdsImpl().lrem(key, count, value);

	}

	@Override
	public String lpop(String key) {
		return getJedisCmdsImpl().lpop(key);

	}

	@Override
	public String rpop(String key) {
		return getJedisCmdsImpl().rpop(key);

	}

	@Override
	public Long sadd(String key, String... member) {
		return getJedisCmdsImpl().sadd(key, member);

	}

	@Override
	public Set<String> smembers(String key) {
		return getJedisCmdsImpl().smembers(key);

	}

	@Override
	public Long srem(String key, String... member) {
		return getJedisCmdsImpl().srem(key, member);

	}

	@Override
	public String spop(String key) {
		return getJedisCmdsImpl().spop(key);

	}

	@Override
	public Set<String> spop(String key, long count) {
		return getJedisCmdsImpl().spop(key, count);

	}

	@Override
	public Long scard(String key) {
		return getJedisCmdsImpl().scard(key);

	}

	@Override
	public Boolean sismember(String key, String member) {
		return getJedisCmdsImpl().sismember(key, member);

	}

	@Override
	public String srandmember(String key) {
		return getJedisCmdsImpl().srandmember(key);

	}

	@Override
	public List<String> srandmember(String key, int count) {
		return getJedisCmdsImpl().srandmember(key, count);

	}

	@Override
	public Long strlen(String key) {
		return getJedisCmdsImpl().strlen(key);

	}

	@Override
	public Long zadd(String key, double score, String member) {
		return getJedisCmdsImpl().zadd(key, score, member);

	}

	@Override
	public Long zadd(String key, Map<String, Double> scoreMembers) {
		return getJedisCmdsImpl().zadd(key, scoreMembers);

	}

	@Override
	public Set<String> zrange(String key, long start, long end) {
		List<String> list = getJedisCmdsImpl().zrange(key, start, end);
		return Sets.newHashSet(list);
	}

	@Override
	public Long zrem(String key, String... member) {
		return getJedisCmdsImpl().zrem(key, member);

	}

	@Override
	public Double zincrby(String key, double score, String member) {
		return getJedisCmdsImpl().zincrby(key, score, member);

	}

	@Override
	public Long zrank(String key, String member) {
		return getJedisCmdsImpl().zrank(key, member);

	}

	@Override
	public Long zrevrank(String key, String member) {
		return getJedisCmdsImpl().zrevrank(key, member);

	}

	@Override
	public Set<String> zrevrange(String key, long start, long end) {
		List<String> list = getJedisCmdsImpl().zrevrange(key, start, end);
		return Sets.newHashSet(list);
	}

	/**
	 * 返回类型有了装换, 建议用zrangeWithScores4Lettuce
	 */

	@Override
	@Deprecated
	public Set<Tuple> zrangeWithScores(String key, long start, long end) {
		Set<Tuple> set = new HashSet<>();
		List<ScoredValue<String>> list = getJedisCmdsImpl().zrangeWithScores(key, start, end);
		for (ScoredValue<String> scoredValue : list) {
			set.add(new Tuple(scoredValue.getValue(), scoredValue.getScore()));
		}
		return set;
	}

	/**
	 * Jedis的zrangeWithScores方法的Lettuce实现方法
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 */
	@Recommend(from = "zrangeWithScores")
	public List<ScoredValue<String>> zrangeWithScores4Lettuce(String key, long start, long end) {
		return getJedisCmdsImpl().zrangeWithScores(key, start, end);
	}

	@Override
	@Deprecated
	public Set<Tuple> zrevrangeWithScores(String key, long start, long end) {
		Set<Tuple> set = new HashSet<>();
		List<ScoredValue<String>> list = getJedisCmdsImpl().zrevrangeWithScores(key, start, end);
		for (ScoredValue<String> scoredValue : list) {
			set.add(new Tuple(scoredValue.getValue(), scoredValue.getScore()));
		}
		return set;
	}

	@Recommend(from = "zrevrangeWithScores")
	public List<ScoredValue<String>> zrevrangeWithScores4Lettuce(String key, long start, long end) {
		return getJedisCmdsImpl().zrevrangeWithScores(key, start, end);
	}

	@Override
	public Long zcard(String key) {
		return getJedisCmdsImpl().zcard(key);

	}

	@Override
	public Double zscore(String key, String member) {
		return getJedisCmdsImpl().zscore(key, member);

	}

	@Override
	public List<String> sort(String key) {
		return getJedisCmdsImpl().sort(key);

	}

	@Override
	@Deprecated
	public Long zcount(String key, double min, double max) {
		return getJedisCmdsImpl().zcount(key, min, max);

	}

	@Override
	@Deprecated
	public Long zcount(String key, String min, String max) {
		return getJedisCmdsImpl().zcount(key, min, max);
	}

	@Override
	@Deprecated
	public Set<String> zrangeByScore(String key, double min, double max) {
		List<String> list = getJedisCmdsImpl().zrangebyscore(key, min, max);
		return Sets.newHashSet(list);
	}

	@Override
	@Deprecated
	public Set<String> zrangeByScore(String key, String min, String max) {
		List<String> list = getJedisCmdsImpl().zrangebyscore(key, min, max);
		return Sets.newConcurrentHashSet(list);
	}

	@Override
	@Deprecated
	public Set<String> zrevrangeByScore(String key, double max, double min) {
		List<String> list = getJedisCmdsImpl().zrevrangebyscore(key, max, min);
		return Sets.newConcurrentHashSet(list);
	}

	@Override
	@Deprecated
	public Set<String> zrangeByScore(String key, double min, double max, int offset, int count) {
		List<String> list = getJedisCmdsImpl().zrangebyscore(key, min, max, offset, count);
		return Sets.newConcurrentHashSet(list);
	}

	@Override
	@Deprecated
	public Set<String> zrevrangeByScore(String key, String max, String min) {
		List<String> list = getJedisCmdsImpl().zrangebyscore(key, max, min);
		return Sets.newConcurrentHashSet(list);
	}

	@Override
	@Deprecated
	public Set<String> zrangeByScore(String key, String min, String max, int offset, int count) {
		List<String> list = getJedisCmdsImpl().zrangebyscore(key, min, max, offset, count);
		return Sets.newConcurrentHashSet(list);
	}

	@Override
	@Deprecated
	public Set<String> zrevrangeByScore(String key, double max, double min, int offset, int count) {
		List<String> list = getJedisCmdsImpl().zrevrangebyscore(key, max, min, offset, count);
		return Sets.newConcurrentHashSet(list);
	}

	@Override
	@Deprecated
	public Set<Tuple> zrangeByScoreWithScores(String key, double min, double max) {
		List<ScoredValue<String>> list = getJedisCmdsImpl().zrangebyscoreWithScores(key, min, max);

		Set<Tuple> set = new HashSet<>();
		for (ScoredValue<String> scoredValue : list) {
			set.add(new Tuple(scoredValue.getValue(), scoredValue.getScore()));
		}
		return set;
	}

	@Override
	@Deprecated
	public Set<Tuple> zrevrangeByScoreWithScores(String key, double max, double min) {
		List<ScoredValue<String>> list = getJedisCmdsImpl().zrevrangebyscoreWithScores(key, max, min);
		Set<Tuple> set = new HashSet<>();
		for (ScoredValue<String> scoredValue : list) {
			set.add(new Tuple(scoredValue.getValue(), scoredValue.getScore()));
		}
		return set;
	}

	@Override
	@Deprecated
	public Set<Tuple> zrangeByScoreWithScores(String key, double min, double max, int offset, int count) {
		List<ScoredValue<String>> list = getJedisCmdsImpl().zrangebyscoreWithScores(key, min, max, offset, count);
		Set<Tuple> set = new HashSet<>();
		for (ScoredValue<String> scoredValue : list) {
			set.add(new Tuple(scoredValue.getValue(), scoredValue.getScore()));
		}
		return set;
	}

	@Override
	@Deprecated
	public Set<String> zrevrangeByScore(String key, String max, String min, int offset, int count) {
		List<String> list = getJedisCmdsImpl().zrevrangebyscore(key, max, min, offset, count);
		return Sets.newConcurrentHashSet(list);
	}

	@Override
	@Deprecated
	public Set<Tuple> zrangeByScoreWithScores(String key, String min, String max) {
		List<ScoredValue<String>> list = getJedisCmdsImpl().zrangebyscoreWithScores(key, min, max);
		Set<Tuple> set = new HashSet<>();
		for (ScoredValue<String> scoredValue : list) {
			set.add(new Tuple(scoredValue.getValue(), scoredValue.getScore()));
		}
		return set;
	}

	@Override
	@Deprecated
	public Set<Tuple> zrevrangeByScoreWithScores(String key, String max, String min) {
		List<ScoredValue<String>> list = getJedisCmdsImpl().zrevrangebyscoreWithScores(key, max, min);
		Set<Tuple> set = new HashSet<>();
		for (ScoredValue<String> scoredValue : list) {
			set.add(new Tuple(scoredValue.getValue(), scoredValue.getScore()));
		}
		return set;
	}

	@Override
	@Deprecated
	public Set<Tuple> zrangeByScoreWithScores(String key, String min, String max, int offset, int count) {
		List<ScoredValue<String>> list = getJedisCmdsImpl().zrevrangebyscoreWithScores(key, min, max, offset, count);
		Set<Tuple> set = new HashSet<>();
		for (ScoredValue<String> scoredValue : list) {
			set.add(new Tuple(scoredValue.getValue(), scoredValue.getScore()));
		}
		return set;
	}

	@Override
	@Deprecated
	public Set<Tuple> zrevrangeByScoreWithScores(String key, double max, double min, int offset, int count) {
		List<ScoredValue<String>> list = getJedisCmdsImpl().zrevrangebyscoreWithScores(key, max, min, offset, count);
		Set<Tuple> set = new HashSet<>();
		for (ScoredValue<String> scoredValue : list) {
			set.add(new Tuple(scoredValue.getValue(), scoredValue.getScore()));
		}
		return set;
	}

	@Override
	@Deprecated
	public Set<Tuple> zrevrangeByScoreWithScores(String key, String max, String min, int offset, int count) {
		List<ScoredValue<String>> list = getJedisCmdsImpl().zrevrangebyscoreWithScores(key, max, min, offset, count);
		Set<Tuple> set = new HashSet<>();
		for (ScoredValue<String> scoredValue : list) {
			set.add(new Tuple(scoredValue.getValue(), scoredValue.getScore()));
		}
		return set;
	}

	@Override
	public Long zremrangeByRank(String key, long start, long end) {
		return getJedisCmdsImpl().zremrangebyrank(key, start, end);
	}

	@Override
	@Deprecated
	public Long zremrangeByScore(String key, double start, double end) {
		return getJedisCmdsImpl().zremrangebyscore(key, start, end);
	}

	@Override
	@Deprecated
	public Long zremrangeByScore(String key, String start, String end) {
		return getJedisCmdsImpl().zremrangebyscore(key, start, end);
	}

	@Override
	@Deprecated
	public Long zlexcount(String key, String min, String max) {
		return getJedisCmdsImpl().zlexcount(key, min, max);
	}

	@Override
	@Deprecated
	public Set<String> zrangeByLex(String key, String min, String max) {
		List<String> list = getJedisCmdsImpl().zrangebylex(key, min, max);
		return Sets.newHashSet(list);
	}

	@Override
	@Deprecated
	public Set<String> zrangeByLex(String key, String min, String max, int offset, int count) {
		List<String> list = getJedisCmdsImpl().zrangebylex(key, min, max, offset, count);
		return Sets.newHashSet(list);
	}

	@Override
	@Deprecated
	public Set<String> zrevrangeByLex(String key, String max, String min) {
		List<String> list = getJedisCmdsImpl().zrevrangebylex(key, Range.create(min, max));
		return Sets.newHashSet(list);
	}

	@Override
	@Deprecated
	public Long zremrangeByLex(String key, String min, String max) {
		return getJedisCmdsImpl().zremrangebylex(key, min, max);
	}

	@Override
	public Long linsert(String key, LIST_POSITION where, String pivot, String value) {
		return getJedisCmdsImpl().linsert(key, LIST_POSITION.BEFORE.equals(where), pivot, value);
	}

	@Override
	public Long lpushx(String key, String... string) {
		return getJedisCmdsImpl().lpushx(key, string);
	}

	@Override
	public Long rpushx(String key, String... string) {
		return getJedisCmdsImpl().rpushx(key, string);
	}

	@Override
	@Deprecated
	public List<String> blpop(String arg) {
		KeyValue<String, String> kvVal = getJedisCmdsImpl().blpop(0, arg);
		return Lists.newArrayList(kvVal.getValue());
	}

	@Override
	@Deprecated
	public List<String> blpop(int timeout, String key) {
		KeyValue<String, String> kvVal = getJedisCmdsImpl().blpop(timeout, key);
		return Lists.newArrayList(kvVal.getValue());
	}

	@Override
	@Deprecated
	public List<String> brpop(String arg) {
		KeyValue<String, String> kvVal = getJedisCmdsImpl().brpop(0, arg);
		return Lists.newArrayList(kvVal.getValue());
	}

	@Override
	@Deprecated
	public List<String> brpop(int timeout, String key) {
		KeyValue<String, String> kvVal = getJedisCmdsImpl().brpop(timeout, key);
		return Lists.newArrayList(kvVal.getValue());
	}

	@Override
	public Long del(String key) {
		return getJedisCmdsImpl().del(key);
	}

	@Override
	public String echo(String string) {
		return getJedisCmdsImpl().echo(string);
	}

	@Override
	public Long move(String key, int dbIndex) {
		return getJedisCmdsImpl().move(key, dbIndex) ? 1L : 0L;
	}

	@Override
	public Long bitcount(String key) {
		return getJedisCmdsImpl().bitcount(key);
	}

	@Override
	public Long bitcount(String key, long start, long end) {
		return getJedisCmdsImpl().bitcount(key, start, end);
	}

	@Override
	public Long bitpos(String key, boolean value) {
		return getJedisCmdsImpl().bitpos(key, value);
	}

	@Override
	public Long pfadd(String key, String... elements) {
		return getJedisCmdsImpl().pfadd(key, elements);
	}

	@Override
	public long pfcount(String key) {
		return getJedisCmdsImpl().pfcount(key);
	}

	@Override
	public Long geoadd(String key, double longitude, double latitude, String member) {
		return getJedisCmdsImpl().geoadd(key, longitude, latitude, member);
	}

	@Override
	public Long exists(String... keys) {
		return getMultiKeyCmdsImpl().exists(keys);
	}

	@Override
	public Long del(String... keys) {
		return getMultiKeyCmdsImpl().del(keys);
	}

	@Override
	public List<String> mget(String... keys) {
		List<String> listStr = new ArrayList<>();
		List<KeyValue<String, String>> list = getJedisCmdsImpl().mget(keys);
		for (String field : keys) {
			for (KeyValue<String, String> kv : list) {
				if (kv.getKey().equals(field)) {
					listStr.add(kv.hasValue() ? kv.getValue() : null);
				}
			}
		}
		return listStr;
	}

	@Override
	public String mset(String... keysvalues) {
		Map<String, String> map = Maps.newHashMap();
		for (int i = 0; i < keysvalues.length; i = i + 2) {
			map.put(keysvalues[i], keysvalues[i + 1]);
		}
		return getMultiKeyCmdsImpl().mset(map);
	}

	@Override
	public Long msetnx(String... keysvalues) {
		Map<String, String> map = Maps.newHashMap();
		for (int i = 0; i < keysvalues.length; i = i + 2) {
			map.put(keysvalues[i], keysvalues[i + 1]);
		}
		return getMultiKeyCmdsImpl().msetnx(map) ? 1L : 0L;
	}

	@Override
	public String rename(String oldkey, String newkey) {
		return getMultiKeyCmdsImpl().rename(oldkey, newkey);
	}

	@Override
	public Long renamenx(String oldkey, String newkey) {
		return getMultiKeyCmdsImpl().renamenx(oldkey, newkey) ? 1L : 0L;
	}

	@Override
	public String rpoplpush(String srckey, String dstkey) {
		return getMultiKeyCmdsImpl().rpoplpush(srckey, dstkey);
	}

	@Override
	public Set<String> sdiff(String... keys) {
		return getMultiKeyCmdsImpl().sdiff(keys);
	}

	@Override
	public Long sdiffstore(String dstkey, String... keys) {
		return getMultiKeyCmdsImpl().sdiffstore(dstkey, keys);
	}

	@Override
	public Set<String> sinter(String... keys) {
		return getMultiKeyCmdsImpl().sinter(keys);
	}

	@Override
	public Long sinterstore(String dstkey, String... keys) {
		return getMultiKeyCmdsImpl().sinterstore(dstkey, keys);
	}

	@Override
	public Long smove(String srckey, String dstkey, String member) {
		return getMultiKeyCmdsImpl().smove(srckey, dstkey, member) ? 1L : 0L;
	}

	@Override
	public Set<String> sunion(String... keys) {
		return getMultiKeyCmdsImpl().sunion(keys);
	}

	@Override
	public Long sunionstore(String dstkey, String... keys) {
		return getMultiKeyCmdsImpl().sunionstore(dstkey, keys);
	}

	@Override
	public Long zinterstore(String dstkey, String... sets) {
		return getMultiKeyCmdsImpl().zinterstore(dstkey, sets);
	}

	@Override
	public Long zunionstore(String dstkey, String... sets) {
		return getMultiKeyCmdsImpl().zunionstore(dstkey, sets);
	}

	@Override
	public String brpoplpush(String source, String destination, int timeout) {
		return getMultiKeyCmdsImpl().brpoplpush(timeout, source, destination);
	}

	@Override
	public Long publish(String channel, String message) {
		return getMultiKeyCmdsImpl().publish(channel, message);
	}

	@Override
	public String pfmerge(String destkey, String... sourcekeys) {
		return getMultiKeyCmdsImpl().pfmerge(destkey, sourcekeys);
	}

	@Override
	public long pfcount(String... keys) {
		return getMultiKeyCmdsImpl().pfcount(keys);
	}

}
